﻿using System;
using System.IO;
using System.Net;
using System.Text;

namespace FTPclient
{
    class FTPHelper
    {

        // 服务器 IP
        public static string FtpServerIP = "";

        // 服务器端口
        public static int FtpServerPort = 21;

        // 用户名
        public static string FtpUserID = "";

        // 密码
        public static string FtpPassword = "";

        public static string FtpURI = "ftp://" + FtpServerIP + ":" + FtpServerPort.ToString();

        public FTPHelper(string serverIP, int serverPort, string userID, string password)
        {
            FtpServerIP = serverIP;
            FtpServerPort = serverPort;
            FtpUserID = userID;
            FtpPassword = password;
            FtpURI = "ftp://" + FtpServerIP + ":" + FtpServerPort.ToString();
        }

        // 给定服务器上的路径，获取路径下所有文件夹
        public string[] get_directories(string path)
        {
            StringBuilder ret = new StringBuilder();
            try
            {
                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(FtpURI + path));
                reqFTP.UseBinary = true;
                reqFTP.KeepAlive = false;
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());
                string line = reader.ReadLine();
                while (line != null)
                {
                    if (line[0] == 'd')
                    {
                        string[] tmp = line.Split();
                        ret.Append(tmp[tmp.Length - 1]);
                        ret.Append("\n");
                    }
                    line = reader.ReadLine();
                }
            }
            catch (Exception ex)
            {
                ret.Clear();
                ret.Append("error");
            }
            return ret.ToString().Split('\n');
        }

        // 给定服务器上的路径，获取路径下所有文件
        public string[] get_files(string path)
        {
            StringBuilder ret = new StringBuilder();
            try
            {
                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(FtpURI + path));
                reqFTP.UseBinary = true;
                reqFTP.KeepAlive = false;
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());
                string line = reader.ReadLine();
                while (line != null)
                {
                    if (line[0] == '-')
                    {
                        //Console.WriteLine(line);
                        string[] tmp = line.Split();
                        ret.Append(tmp[tmp.Length - 1]);
                        ret.Append("\n");
                    }
                    line = reader.ReadLine();
                }
            }
            catch (Exception ex)
            {
                ret.Append("error");
            }
            return ret.ToString().Split('\n');
        }

        // 从服务器下载 RemoteFileName ，保存至 LocalFileName
        public void download(string RemoteFileName, string LocalFileName)
        {
            FtpWebRequest reqFTP, FTPsize;
            Stream ftpStream = null;

            try
            {
                FileStream outputStream = null;
                long offset = 5;
                if (File.Exists(LocalFileName))
                {
                    Console.WriteLine("OK");
                    using (outputStream = new FileStream(LocalFileName, FileMode.Open))
                    {
                        offset = outputStream.Length;
                    }
                }

                Console.WriteLine(offset);
                // 获取需下载的文件大小
                Console.WriteLine(FtpURI + RemoteFileName);
                FTPsize = (FtpWebRequest)FtpWebRequest.Create(FtpURI + RemoteFileName);
                FTPsize.UseBinary = true;
                FTPsize.ContentOffset = offset;
                FTPsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                FTPsize.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse response = (FtpWebResponse)FTPsize.GetResponse();
                long totalBytes = response.ContentLength; // 文件总长度
                response.Close();

                Console.WriteLine(totalBytes);

                reqFTP = (FtpWebRequest)FtpWebRequest.Create(FtpURI + "/" + RemoteFileName);
                reqFTP.UseBinary = true;
                reqFTP.KeepAlive = false;
                reqFTP.ContentOffset = offset;
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                response = (FtpWebResponse)reqFTP.GetResponse();
                ftpStream = response.GetResponseStream();

                long totalDownloadedByte = 0;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                // 初始化进度条
                while (readCount > 0)
                {
                    totalDownloadedByte = readCount + totalDownloadedByte;
                    outputStream = new FileStream(LocalFileName, FileMode.Open);
                    outputStream.Write(buffer, 0, readCount);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                    outputStream.Dispose();
                    // 更新进度条
                }
                ftpStream.Close();
                outputStream.Close();
                response.Close();
               
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        // 获取远程主机文件大小
        public long getRemoteFileSize(string RemoteFileName)
        {
            try
            {
                FtpWebRequest FTPsize = (FtpWebRequest)FtpWebRequest.Create(FtpURI + RemoteFileName);
                FTPsize.UseBinary = true;
                FTPsize.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                FTPsize.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse response = (FtpWebResponse)FTPsize.GetResponse();
                long totalBytes = response.ContentLength; // 文件总长度
                response.Close();
                return totalBytes;
            }
            catch
            {
                return 0;
            }
        }

        // 上传 LocalFileName 至 RemoteFileName
        public void upload(string LocalFileName, string RemoteFileName)
        {
            try
            {
                FileInfo fileInf = new FileInfo(LocalFileName);
                long allbye = (long)fileInf.Length;
                if (!File.Exists(RemoteFileName))
                {
                    RemoteFileName += "/";
                    string path = null;
                    for (int i = LocalFileName.Length; i >= 1; i--)
                    {
                        if (LocalFileName[i - 1] != '\\')
                        {
                            path = LocalFileName[i - 1] + path;
                        }
                        else
                        {
                            break; 
                        }
                    }
                    RemoteFileName += path;
                    File.Create(RemoteFileName).Close();
                }
                long startfilesize = getRemoteFileSize(RemoteFileName);
                Console.WriteLine(startfilesize);
                long startbye = startfilesize;
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(FtpURI + RemoteFileName);
                reqFTP.Credentials = new NetworkCredential(FtpUserID, FtpPassword);
                reqFTP.KeepAlive = false;
                reqFTP.Method = WebRequestMethods.Ftp.AppendFile;
                reqFTP.UseBinary = true;
                reqFTP.ContentLength = fileInf.Length;
                int buffLength = 2048;
                byte[] buff = new byte[buffLength];
                FileStream fileStream = fileInf.OpenRead();
                Stream uploadStream = null;
                uploadStream = reqFTP.GetRequestStream();
                //fileStream.Seek(startfilesize, 0);
                int contentLen = fileStream.Read(buff, 0, buffLength);
                Console.WriteLine(contentLen);
                // 初始化进度条
                while (contentLen != 0)
                {
                    uploadStream.Write(buff, 0, contentLen);
                    contentLen = fileStream.Read(buff, 0, buffLength);
                    startbye += contentLen;
                    // 更新进度条
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //public static void dfMain_1() {
        //    FTPHelper obj =  new FTPHelper("localhost", 21, "user", "uesr");
        //    string[] s = obj.get_files("/");
        //    foreach (string ss in s) {
        //        Console.WriteLine(ss);
        //    }
        //    obj.upload("./hello-world.cs", "/hello-world.cs");
        // }
    }
}


